<?php
	/**
	 * CodeGenerator controller class
	 *
	 * generates php code based on the data from the database	 
	 * @package Generators
	 * @author Perkin Anton
	 * @version 1.1
	 */
	class CodeGeneratorController extends Controller
	{
		/**
	 	 * page title
	 	 */
		public $page_title = LANG_CODE_GENERATOR;

		/**
	 	 * name
	 	 */
		public $name = 'CodeGenerator';
		
		/**
	 	 * page layout
	 	 */
		public $layout = 'main';
		
		/**
	 	 * necessary helpers
	 	 */
		public $helpers = array ('html', 'htmlx');
		
		/**
	 	 * necessary javascript files
	 	 */
		public $javascript = array("TreeMenu", "generator");
		
		/**
	 	 * necessary components
	 	 */
		public $components = array ("TreeMenu");
		
		/**
	 	 * string every php file begins with
	 	 */
		public $phpFileStart = "<?php";

		/**
	 	 * string every php file ends with
	 	 */
		public $phpFileEnd = "\n?>";
		
		/**
		 * Credits
		 *
		 * @var string
		 */
		public $credits;
		
		/**
		 * Author
		 *
		 * @var string
		 */
		public $author = 'Anton Perkin';
		
		/**
		 * integer data types
		 */
		public $numberDataTypes = array('int', 'integer', 'bigint', 'longint', 'smallint', 'decimal', 'float');
		
		/**
		 * string data types
		 */
		public $stringDataTypes = array('varchar', 'char');

		/**
		 * string data types
		 */
		public $textDataTypes = array('text', 'tinytext');

		/**
		 * date data types
		 */
		public $dateDataTypes = array('date', 'datetime');
		
		/**
		 * string data types
		 */
		public $booleanDataTypes = array('bit', 'tinyint');

		/**
		 * string language constants
		 */
		public $languageConstants = array();
		
		/**
		 * name for field which means parent id
		 *
		 * @var string
		 */
		public $parentId = 'parent_id';
		
		/**
		 * name of the backup folder
		 *
		 * @var string
		 */
		public $backupFolder = "./app/spanel_backup/generator/";
						
		/**
		 * system database field names, which should not be added to the generated code
		 */
		public $escapedFieldNames = array('deleted');
		
		/**
		 * max_quantity of the backups in $backupFolder
		 */
		public $max_quantity = 4;

		/**
		 * name for field which means deleting
		 *
		 * @var string
		 */
		public $sortBy = 'sort_by';
		
		/**
		 * name for field which means deleting
		 *
		 * @var string
		 */
		public $sortMethod = 'sort_method';
		
		/**
		 * what entry to begin from 
		 *
		 * @var string
		 */
		public $pageOffset = 'page_offset';		
		
		/**
		 * how many entries to show
		 *
		 * @var string
		 */
		public $pageNumber = 'page_number';
		
		/**
		 * how many entries will be shown indeed
		 *
		 * @var string
		 */
		public $numRows = 'num_rows';
		
		/**
		 * name for field which means deleting
		 *
		 * @var string
		 */
		public $deletingFieldName = 'deleted';
			
		/**
		 * ending for key fields
		 *
		 * @var string
		 */
		public $keyFieldPostfix = '_id';
		
		/**
		 * ending for name fields
		 *
		 * @var string
		 */
		public $nameFieldPostfix = '_name';
		
		/**
		 * Database table prefix
		 *
		 * @var string
		 */
		public $tablePrefix = 't_';

		/**
		 * Database stored procedure prefix
		 *
		 * @var string
		 */
		public $storedProcedurePrefix = 'sp_';
		
		/**
		 * Default layout for the generated papes
		 *
		 * @var string
		 */
		public $defaultLayout = 'main';
		
		/**
		 * Default module for the generated papes
		 *
		 * @var string
		 */
		public $defaultModule = 'administration';
		
		
		/**
		 * Database stored procedure prefix
		 *
		 * @var string
		 */
		public $defaultGridAction = 'view';
		
		/**
		 * default helpers
		 *
		 * @var array
		 */
		public $defaultHelpers = array('grids', 'toolbars');

		/**
		 * default JS
		 *
		 * @var array
		 */
		public $defaultJS = array();
		
		/**
		 * Default class constructor
		 *
		 */
		function __construct()
		{
			$this->credits = "\n\t/**\n\t * Generated by SpherusPHPCodegenerator on ".date("Y-d-m H:i:s");
			$this->credits .= "\n\t * @author ".$this->author;
			$this->credits .= "\n\t * @version 1.0";
			$this->credits .= "\n\t*/\n";
			include_once(SPANEL.SEPARATOR."classes".SEPARATOR."DBGenerator.php");
		}

		
		# GENERAL FUNCTIONS #
		
		/**
	 	 * makes the name plural
	 	 */
		function Pluralize($name)
		{
			$last_char = substr($name, -1);

			switch ($last_char)
			{
				case 'y': $system_name = substr($name, 0, strlen($name)-1).'ies'; break;
				case 's': case 'x': case 'h': $system_name = $name.'es'; break;
//				case 's': case 'o': case 'x': case 'h': $system_name = $name.'es'; break;
				default: $system_name = $name.'s'; break;
			}
			return $system_name;
		}
		
		/**
	 	 * makes the name singular
	 	 */
		function Singularize($name)
		{
			if (eregi("(ies)$", $name)) $name = substr($name, 0, strlen($name)-3).'y';
			else 
				if (eregi("^.+(o|x|ss|sh|ch|zz)(es)$", $name)) $name = substr($name, 0, strlen($name)-2);
			else 
				if (eregi("(s)$", $name)) $name = substr($name, 0, strlen($name)-1);	
			else
				$name = substr($name, 0, strlen($name)-1);
			
			return $name;
		}
		
		/**
		 * Return the Camel Cased representation of the givemn string
		 *
		 * @param string $name string to be parsed
		 * @return string camel cased name
		 */
		function CamelCase($name)
		{
			$name_array = explode('_', $name);
			foreach ($name_array as &$elem)
			{
				$elem = ucfirst($elem);
			}
			$name = implode($name_array);
			return $name;
		}
		
		/**
		 * Converts string to language constant
		 *
		 * @param string $string
		 * @return string
		 */
		function StringToLanguageConstant($string)
		{
			return 'LANG_'.strtoupper($string);
		}
		
		/**
	 	 * sets system field types and subtypes
	 	 */
		function SetSystemFieldTypes()
		{
			//field types
			$this->field_types = array
			(
				'1' => array
				(
					'id' => 'bigint', 
					'name' => LANG_BIGINT
				),
				'2' => array
				(
					'id' => 'varchar', 
					'name' => LANG_VARCHAR
				),
				'3' => array
				(
					'id' => 'text', 
					'name' => LANG_TEXT
				),
				'4' => array
				(
					'id' => 'date', 
					'name' => LANG_DATE
				),
				'7' => array
				(
					'id' => 'datetime', 
					'name' => LANG_DATETIME
				),
				'5' => array
				(
					'id' => 'decimal', 
					'name' => LANG_DECIMAL
				),
				'6' => array
				(
					'id' => 'bit', 
					'name' => LANG_BIT
				)
			);
			
			//field subtypes
			$this->field_subtypes = array
			(
				'1' => array
				(
					'id' => 'percent', 
					'name' => LANG_PERCENT
				),
				'2' => array
				(
					'id' => 'email', 
					'name' => LANG_EMAIL
				),
				'3' => array
				(
					'id' => 'url', 
					'name' => LANG_URL
				),
				'4' => array
				(
					'id' => 'password', 
					'name' => strtolower(LANG_PASSWORD)
				),
				'5' => array
				(
					'id' => 'image', 
					'name' => strtolower(LANG_IMAGE)
				)
			);
		}

		/**
	 	 * sets system model features
	 	 */
		function SetSystemModelFeatures()
		{
			//model features
			$this->model_features_string = array('name', 'type', 'sub_type', 'table_name', 'length', 'min_value', 'max_value', 'default_value', 'by_default');
			$this->model_features_boolean = array('primary_key', 'not_null');
		}
		
		/**
	 	 * deletes MVC files
	 	 * @param $file_name name of the file
	 	 */
		function DeleteFiles($file_name)
		{
			unlink("././app/models/".$file_name.'.php');
			unlink("././app/controllers/".$file_name.'.php');
		}
		
		/**
	 	 * deletes procedures
	 	 */
		function DeleteProcedures()
		{	
			$proc_arr = array(
					'stored_procedure_delete',
					'stored_procedure_get',
					'stored_procedure_insert',
					'stored_procedure_list',
					'stored_procedure_list_paged',
					'stored_procedure_update'
				   );
			foreach ($proc_arr as $value)
			{
				$dropSQL = "IF EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[dbo].[{$_SESSION[mvc][$value]}]') AND type in (N'P')) DROP PROCEDURE [dbo].[{$_SESSION[mvc][$value]}]";
				
				//erase previous procedures
				$this->controller_model->Execute('', '', $dropSQL);
			}
		}
		
		/**
		 * Generates comment according to the Zend PHP Documentor standard
		 */
		function GenerateComment($comment = '', $params = null, $options= null, $outdent_number = 2)
		{
			$outdent = '';
			for ($i = 0; $i < $outdent_number; $i++)
			{
				$outdent .= "\t";
			}
			
			$result = "\n$outdent/**\n$outdent * $comment";
			
			if (!empty($options))
			{
				foreach ($options as $key=>$value)
				{
					$result .= "\n$outdent * @$key $value";
				}
			}
			
			if (!empty($params))
			{
				foreach ($params as $param)
				{
					$result .= "\n$outdent * @param $param";
				}
			}
			$result .= "\n$outdent*/\n";
			return $result;
		}

		/**
		 * Sets the default values for the generator
		 */
		function SetDefaults()
		{
			$this->data[layout] = $this->defaultLayout;
			$this->data[module] = $this->defaultModule;
			$this->data[model_variables] = true;
			$this->data[controller_functions] = true;
			
			foreach ($this->defaultHelpers as $helper)
			{
				$this->data[helpers][$helper] = true;
			}
			
			foreach ($this->defaultJS as $js)
			{
				$this->data[js][$js] = true;
			}
		}
		
		/**
		 * gets primary key from the elements' array
		 * 
		 * @param $elements elements' array
		 */
		function GetPrimaryKey($elements)
		{
			foreach ($elements as $element)
			{
				if ($element[primary_key] == true)
				{
					return $element;
				}
			}
		}
		
		/**
		 * Returns whether the field is readonly (disabled) or not
		 *
		 * @param string $string attribute string
		 * @return boolean
		 */
		function IsReadonly($string)
		{
			return (strstr($string, 'readonly')||strstr($string, 'disabled')) ? true : false;
		}
		
		/**
		 * Parses elements array for the tree menu 
		 *
		 * @param array $elements
		 * @return array
		 */
		function ElementsToTreeMenu($elements, $table_name, $stored_procedures)
		{
			$results = array
			(
				'0' => array
				(
					'name' => ucfirst(LANG_CODE_GENERATOR),
					'url' => '',
					'sub' => array
					(
						'0' => array
						(
							'name' => LANG_CONFIGURATION,
							'url' => '#configuration',
						),
						'1' => array
						(
							'name' => LANG_HELPERS,
							'url' => '#helpers',
						),
						'2' => array
						(
							'name' => LANG_JS_FILES,
							'url' => '#js',
						),
						'3' => array
						(
							'name' => LANG_FIELDS,
							'url' => '#fields',
						),
						'4' => array
						(
							'name' => LANG_STORED_PROCEDURES,
							'url' => '#sp',
						)
					)
				)
			);
			
			//generates the result array
			foreach ($elements as $element)
			{
				if (empty($element[name])) continue;
				
				$type = $element[type];
				$not_null = $element[not_null] ? 'not null' : 'null';
				$length = !empty($element[length]) ? "($element[length])" : '';
				$key = !empty($element[primary_key]) ? 'PK, ' : (!empty($element[foreign_model]) ? 'FK, ' : '');
				$table = !empty($element[table_name]) ? $element[table_name] : $table_name;
				
				//creates array for each table
				$results[0][sub][3][sub][$table][name] = $table;
				$results[0][sub][3][sub][$table][url] = null;
				
				$result[name] = $element[name]." ($key$type$length, $not_null)";
				$result[url] = '#'.$element[name];
				$results[0][sub][3][sub][$table][sub][] = $result;
			}
			
			if (!empty($stored_procedures))
			{
				foreach ($stored_procedures as $key=>$value)
				{
					$result[name] = $key;
					$result[url] = '#'.$key;
					$results[0][sub][4][sub][] = $result;
				}
			}
			
			return $results;
		}
		
		/**
		 * Returns the array for the generated code tree menu
		 *
		 * @return array
		 */
		function GetGeneratedCodeMenuArray()
		{
			return array
			(
				'root' => array
				(
					'name' => ucfirst(LANG_GENERATED_CODE),
					'url' => '#',
					'sub' => array
					(
						'menu' => array
						(
							'name' => LANG_MENU_ITEM_CODE,
							'url' => '#menu_item',
						),
						'const' => array
						(
							'name' => LANG_LANG_CONSTANTS,
							'url' => '#lang_const',
						),
						'model' => array
						(
							'name' => LANG_MODEL,
							'url' => '#model',
						),
						'controller' => array
						(
							'name' => LANG_CONTROLLER,
							'url' => '#controller',
						),
						'views' => array
						(
							'name' => LANG_VIEWS,
							'url' => '',
							'sub' => array
							(
								'add' => array
								(
									'name' => LANG_ADD,
									'url' => '#add_page'
								),
								'edit' => array
								(
									'name' => LANG_EDIT,
									'url' => '#edit_page'
								),
								'view' => array
								(
									'name' => LANG_VIEW,
									'url' => '#view_page'
								),
								'delete' => array
								(
									'name' => LANG_DELETE,
									'url' => '#delete_page'
								),
								'index' => array
								(
									'name' => LANG_LIST,
									'url' => '#index_page'
								),
							)
						),
					)
				)
			);
		}
		
		
		# ACTIONS GENERATION #
		
		/**
	 	 * generates index function for the Controller
	 	 * @param array data
	 	 */
		function GenerateIndexFunction($data)
		{
			$result = $this->GenerateComment("Main controller page");
			
			$result .= "\t\tfunction Index()\n";
			$result .= "\t\t{";
			
			$result .= "\n\t\t\t".'$this->DefaultParameters();';
			if ($this->tree_structure)
			{
				$result .= "\n\t\t\t".'if (!isset($this->request->get['.$this->parentId.'])) $this->request->get['.$this->parentId.']=\'0\';';
			}	
			$result .= "\n\t\t\t
			\$parameters = array('num_rows');
			\$this->data[\$this->name] = \$this->controller_model->ListItemsPaged(\$this->request->get, '', \$parameters);
			\$this->data['num_rows'] = \$parameters['num_rows'];\n";
			$result .= "\t\t}\n";
			
			return $result;
		}		

		/**
	 	 * generates index function for the Controller
	 	 * @param array data
	 	 */
		function GenerateAddFunction($data)
		{			
			$redirection = '';
			if ($this->tree_structure)
			{
				$redirection = '.$_SESSION[$this->name][indexGetUrl]';
			}
			
			$result = $this->GenerateComment("Adds an item");
			if ($this->tree_structure)
			{
				$result .= "\n\t\t".'function Add($parent_id)'."\n\t\t{";
				$result .= "\n\t\t".'$this->data['.$this->parentId.'] = $parent_id;';
				$result .= "\n\t\t".'$this->data[the_parent] = $this->controller_model->Get($parent_id);';
			}	
			else 
				$result .= "\t\tfunction Add()
		{";
			
			$result .= "\n\t\t\t//reference data";
			foreach ($data['elements'] as $element)
			{
				if (!empty($element['foreign_model']))
				{
					$result .= "\n\t\t\t\$this->data['{$element[foreign_model]}'] = \$this->GetModelObject('$element[foreign_model]')->ListItems(array('sort_by'=>'', 'sort_method'=>''));";
				}
			}
		
			$result .= "\n							
			if (HTTPContext::IsPostBack())
			{
				if (\$this->controller_model->Update(\$this->request->post))
				{
					\$this->Redirect(\$this->name$redirection);
				}
				else
				{
					\$this->data[\$this->name] = \$this->request->post;				
				}
			}
			else
			{

			}	
		}\n";
			return $result;
		}		
		
		/**
	 	 * generates index function for the Controller
	 	 * @param array data
	 	 */
		function GenerateViewFunction($data)
		{
			$result = $this->GenerateComment("Displays an item", array('integer $id item id'));
			
			$result .= "\t\tfunction View(\$id)
		{
			//{$data['name']}
			\$this->data[\$this->name] = \$this->controller_model->Get(\$id);";
			if ($this->tree_structure)
			{
				$result .= "\n\t\t\t".'$this->data[the_parent] = $this->controller_model->Get($this->data[$this->name]['.$this->parentId.']);';
			}
			$result .= "\n\t\t}\n";
						
			return $result;
		}		
		
		/**
	 	 * generates index function for the Controller
	 	 * @param array data
	 	 */
		function GenerateEditFunction($data)
		{
			$redirection = '';
			if ($this->tree_structure)
			{
				$redirection = '.$_SESSION[$this->name][indexGetUrl]';
			}
			
			$result = $this->GenerateComment("Edits an item", array('integer $id item id'));
			$result .= "\t\tfunction Edit(\$id)
		{";
			
			$result .= "\n\t\t\t//reference data";
			foreach ($data['elements'] as $element)
			{
				if (!empty($element['foreign_model']))
				{
					$result .= "\n\t\t\t\$this->data['{$element[foreign_model]}'] = \$this->GetModelObject('$element[foreign_model]')->ListItems();";
				}
			}
			
			$result.="\n
			//{$data['name']}
			\$this->data[\$this->name] = \$this->controller_model->Get(\$id);";			
			
			if ($this->tree_structure)
			{
				$result .= "\n\t\t\t".'$this->data[the_parent] = $this->controller_model->Get($this->data[$this->name]['.$this->parentId.']);';
			}
			
			$result .= "\n\n\t\t\tif (HTTPContext::IsPostBack())
			{
				if (\$this->controller_model->Update(\$this->request->post))
				{
					\$this->Redirect(\$this->name$redirection);
				}
				else
				{
					\$this->data[\$this->name] = \$this->request->post;				
				}
			}
			else
			{

			}	
		}\n";			
			return $result;
		}		
		
		/**
	 	 * generates index function for the Controller
	 	 * @param array data
	 	 */
		function GenerateDeleteFunction($data)
		{
			$result = $this->GenerateComment("Deletes an item", array('integer $id item id', 'boolean $confirm delete confirmation'));
			$result .= "\t\tfunction Delete(\$id, \$confirm = 0)
		{ 
			if (\$confirm)
			{
				\$this->controller_model->Delete(\$id);
				\$this->Redirect(\$this->name);
			}
			else
			{
				\$this->layout = 'empty';
				\$this->data[\$this->name]['id'] = \$id;
			}
		}";			
			return $result;
		}		
		
		/**
	 	 * generates controller class variables
	 	 * @param array data
	 	 */
		function GenerateControllerClassVariables($data)
		{
			$result = "\t\tpublic \$page_title = {$data[page_title]};\n";
			$result .= "\t\tpublic \$layout = '{$data[layout]}';\n";
			$result .= "\t\tpublic \$module = '{$data[module]}';\n";
			$result .= "\t\tpublic \$name = '{$data[system_name]}';\n";
			$result .= "\t\tpublic \$localName = {$data[page_title]};\n";
			$result .= "\t\tpublic \$metaName = ".str_replace('LANG_', 'META_NAME_', $data[page_title]).";\n";
			$result .= "\t\tpublic \$metaDescription = ".str_replace('LANG_', 'META_DESCRIPTION_', $data[page_title]).";\n";
			
			//helpers
			$helpers_string = "'html', 'htmlx', ";
			if (!empty($data[helpers]))
			{
				foreach ($data[helpers] as $key=>$value)
				{
					$helpers_string .= "'".$key."', ";
				}
			}
			$helpers_string = ereg_replace('(, )$', '', $helpers_string);
			$result .= "\t\tpublic \$helpers = array($helpers_string);\n";
			
			//js files
			$js_string = '';
			if (!empty($data[js]))
			{
				foreach ($data[js] as $key=>$value)
				{
					$js_string .= "'".$key."', ";
				}
			}
			$js_string = ereg_replace('(, )$', '', $js_string);
			$result .= "\t\tpublic \$javascript = array($js_string);\n";
			
			return $result;
		}		

		
		# INPUT FIELDS' GENERATION #

		/**
		 * generates input rows according to their type
		 */
		function GenerateInputRows($elements, $common_attributes = null)
		{
			$inputRows = '';
			
			foreach ($elements as $element)
			{
				$array_moved = false;
				
				//skips if necessary
				if ((empty($element[app_name]))||(empty($element[title]))||(!empty($element[table_name]))||($element[primary_key]) || $element[name] == $this->parentId)
				{
					next(&$elements);
					continue;
				}
				
				//adds language constant
				if ((!in_array($element[title], $this->languageConstants))&&(!empty($element[title])))
				{
					array_push(&$this->languageConstants, $element[title]);
				}				
				
				//if string data type
				if (in_array($element[type], $this->stringDataTypes))
				{
					if ($element[sub_type] == 'password')
					{
						$inputRows .= $this->GeneratePasswordRow($element, $common_attributes);
					}
					else if ($element[sub_type] == 'image')
					{
						$inputRows .= $this->GenerateImageRow($element, $common_attributes);
					}
					else
					{
						$inputRows .= $this->GenerateInputTextRow($element, $common_attributes);
					}
				}
				//if text data type
				elseif (in_array($element[type], $this->textDataTypes))
				{
					$inputRows .= $this->GenerateTextareaRow($element, $common_attributes);
				}
				//if numeric data type
				elseif (in_array($element[type], $this->numberDataTypes))
				{
					if ((!empty($element[foreign_model])))
					{
						if ($this->IsReadonly($common_attributes))
						{
							$element = next(&$elements);
							$array_moved = true;
							
							$inputRows .= $this->GenerateInputTextRow($element, $common_attributes);
						}
						else
						{
							$inputRows .= $this->GenerateSelectboxRow($element, $common_attributes);
						}
					}
					else
					{
						$inputRows .= $this->GenerateInputTextRow($element, $common_attributes);
					}
				}
				//if date data type
				elseif (in_array($element[type], $this->dateDataTypes))
				{
					$inputRows .= $this->GenerateInputDateRow($element, $common_attributes);
				}
				//if boolean data type
				elseif (in_array($element[type], $this->booleanDataTypes)) 
				{
					$inputRows .= $this->GenerateCheckboxRow($element, $common_attributes);
				}
				
				if (!$array_moved) next(&$elements);
			}
			return $inputRows;
		}
		
		/**
		 * generates inputTextRow
		 * @param array $element row
		 */
		function GenerateInputTextRow($element, $common_attributes = null)
		{
			return "\n\t\t\$this->helpers->htmlx->InputTextRow({$element[title]}, '{$element[app_name]}', \$this->data[\$this->name]['{$element[app_name]}'], '$common_attributes');";
		}

		/**
		 * generates PasswordRow
		 * @param array $element row
		 */
		function GeneratePasswordRow($element, $common_attributes = null)
		{
			return "\n\t\t\$this->helpers->htmlx->PasswordRow({$element[title]}, '{$element[app_name]}', \$this->data[\$this->name]['{$element[app_name]}'], '$common_attributes');";
		}		

		/**
		 * generates image row 
		 * @param $element
		 * @param $common_attributes
		 * @return unknown_type
		 */
		function GenerateImageRow($element, $common_attributes = null)
		{
			return "\n\t\t\$this->helpers->htmlx->InputImageRow({$element[title]}, '{$element[app_name]}', \$this->name.SEPARATOR.\$this->data[\$this->name][id], \$this->data[\$this->name][{$element[app_name]}], \$this->data[message][upload]);";
		}		
		
		/**
		 * generates CheckboxRow
		 * @param array $element row
		 */
		function GenerateCheckboxRow($element, $common_attributes = null)
		{
			return "\n\t\t\$this->helpers->htmlx->CheckboxRow({$element[title]}, '{$element[app_name]}', \$this->data[\$this->name]['{$element[app_name]}'], '$common_attributes');";
		}
		
		/**
		 * generates ComboboxRow
		 * @param array $element row
		 */
		function GenerateComboboxRow($element, $common_attributes = null)
		{
			return "\n\t\t\$this->helpers->htmlx->ComboboxRow({$element[title]}, '{$element[app_name]}', \$this->data['{$element[foreign_model]}'], \$this->data[\$this->name]['{$element[app_name]}'], '$common_attributes');";
		}

		/**
		 * generates SelectboxRow
		 * @param array $element row
		 */
		function GenerateSelectboxRow($element, $common_attributes = null)
		{
			return "\n\t\t\$this->helpers->htmlx->SelectboxRow({$element[title]}, '{$element[app_name]}', \$this->data['{$element[foreign_model]}'], \$this->data[\$this->name]['{$element[app_name]}'], '$common_attributes');";
		}
		
		/**
		 * generates InputDataRow
		 * @param array $element row
		 */
		function GenerateInputDateRow($element, $common_attributes = null)
		{
			return "\n\t\t\$this->helpers->htmlx->InputDateRow({$element[title]}, '{$element[app_name]}', \$this->data[\$this->name]['{$element[app_name]}'], '$common_attributes');";
		}
		
		/**
		 * generates hidden field
		 * @param array $element row
		 */
		function GenerateInputHidden($element)
		{
			return "\n\t\t\$this->helpers->html->Hidden('{$element[app_name]}', \$this->data[\$this->name]['{$element[app_name]}']);";
		}
		
		/**
		 * generates TextareaRow
		 * @param array $element row
		 */
		function GenerateTextareaRow($element, $common_attributes = null)
		{
			return "\n\t\t\$this->helpers->htmlx->TextareaRow({$element[title]}, '{$element[app_name]}', \$this->data[\$this->name]['{$element[app_name]}'], '$common_attributes');";
		}
		
		
		# ACTION PAGES' GENERATION #
		
		/**
	 	 * generates add page
	 	 * @param array data
	 	 */
		function GenerateAddPage($data)
		{			
			//creates the file with the specified name
			$fp = fopen('app'.SEPARATOR.'views'.SEPARATOR.trim($data['file_name']).SEPARATOR.'add.php', 'w+');
			
			$redirection = '';
			if ($this->tree_structure)
			{
				$redirection = '.$_SESSION[$this->name][indexGetUrl]';
				$formActionId = '.$this->data['.$this->parentId."]";
			}
			else
			{
				$formActionId = '';
			}
			
			//page header
			$header = "\n\t//title\n\t\$this->helpers->htmlx->MenuText1(\$this->localName.': '.LANG_ADD, 'add.gif');";
			
			$form_start = "\n\n\t//form\n\tXHTML::Form('/'.\$this->name.'/add/'".$formActionId.");";
			$eva_begin = "\n\n\techo '<table class=\"eva\">';";
			$eva_end = "\n\techo '</table>';";
			$form_end = "\n\techo '</form>';";
			
			// if there is parent id field
			if ($this->tree_structure)
			{
				$inputRows = "\n\t\t".'$this->helpers->html->Hidden("'.$this->parentId.'", $this->data['.$this->parentId.']);';
			}
			
			//generates input rows
			$inputRows .= $this->GenerateInputRows($data['elements']);
			
			//generates submit table
			$submitTable = "\n\n\t//submit\n\t\$this->helpers->htmlx->submitTable('submit1', \$this->name$redirection.'/');\n";
			
			//file content
			$content = $this->phpFileStart.$this->credits.$header.$form_start.$eva_begin.$inputRows.$eva_end.$submitTable.$form_end.$this->phpFileEnd;
			
			//writes to the file
			fwrite($fp, $content);
			
			//closes the file
			fclose($fp);
		}		

		/**
	 	 * generates edit page
	 	 * @param array data
	 	 */
		function GenerateEditPage($data)
		{
			//creates the file with the specified name
			$fp = fopen('app'.SEPARATOR.'views'.SEPARATOR.trim($data['file_name']).SEPARATOR.'edit.php', 'w+');
			
			$redirection = '';
			if ($this->tree_structure)
			{
				$redirection = '.$_SESSION[$this->name][indexGetUrl]';
			}
			
			$toolbar_elements = array
			(
				'0' => array
				(
					'name'=>'list_button',
					'image'=>'btnListLarge.gif',
					'text'=>'LANG_LIST',
					'url'=>'"/".$this->name'
				)
			);
			$toolbar_array = $this->GenerateToolbarArray($toolbar_elements)."\n";
			
			$primary_element = $this->GetPrimaryKey($data[elements]);
			
			//page header
			$header = "\n\t//title\n\t\$this->helpers->htmlx->MenuText1(\$this->localName.': '.LANG_EDIT, 'edit.gif');";
			
			$form_start = "\n\n\t//form\n\tXHTML::Form('/'.\$this->name.'/edit/'.\$this->data[\$this->name][{$primary_element['app_name']}]);";
			$toolbar = "\n\t\n\t//toolbar\n\t\$this->helpers->toolbars->Toolbar(\$tool_buttons);";
			$eva_begin = "\n\n\techo '<table class=\"eva\">';";
			$eva_end = "\n\techo '</table>';";
			$form_end = "\n\techo '</form>';";
						
			$hidden_data = $this->GenerateInputHidden($primary_element);
			
			// if there is parent id field
			if ($this->tree_structure)
			{
				$inputRows = "\n\t\t".'$this->helpers->html->Hidden("'.$this->parentId.'", $this->data[$this->name]['.$this->parentId.']);';
			}
			
			//generates input rows
			$inputRows .= $this->GenerateInputRows($data[elements]);
			
			//generates submit table
			$submitTable = "\n\n\t//submit\n\t\$this->helpers->htmlx->submitTable('submit1', \$this->name$redirection.'/');\n";
			
			//file content
			$content = $this->phpFileStart.$this->credits.$toolbar_array.$header.$form_start.$toolbar.$eva_begin.$hidden_data.$inputRows.$eva_end.$submitTable.$form_end.$this->phpFileEnd;
			
			//writes to the file
			fwrite($fp, $content);
			
			//closes the file
			fclose($fp);
		}		
		
		/**
	 	 * generates delete page
	 	 * @param array data
	 	 */
		function GenerateDeletePage($data)
		{
			//making replication
//			$this->copyFiles('delete', 'views/'.$_POST[system_name], 'delete');
			
			//creates the file with the specified name
			$fp = fopen('app'.SEPARATOR.'views'.SEPARATOR.trim($data[file_name]).SEPARATOR.'delete.php', 'w+');
			
			//generates delete table
			$confirmDeleteTable = "\n\t\$this->helpers->htmlx->confirmDeleteTable(\$this->data[\$this->name]['id']);";
			
			//file content
			$content = $this->phpFileStart.$this->credits.$confirmDeleteTable.$this->phpFileEnd;
			
			//writes to the file
			fwrite($fp, $content);
			
			//closes the file
			fclose($fp);
		}		

		/**
	 	 * generates view page
	 	 * @param array data
	 	 */
		function GenerateViewPage($data)
		{
			//making replication
//			$this->copyFiles('view', 'views/'.$_POST[system_name], 'view');
			
			//creates the file with the specified name
			$fp = fopen('app'.SEPARATOR.'views'.SEPARATOR.trim($data['file_name']).SEPARATOR.'view.php', 'w+');

			$toolbar_elements = array
			(
				'0' => array
				(
					'name'=>'list_button',
					'image'=>'btnListLarge.gif',
					'text'=>'LANG_LIST',
					'url'=>'"/".$this->name'
				),
				'1' => array
				(
					'name'=>'edit_button',
					'image'=>'btnEditLarge.gif',
					'text'=>'LANG_EDIT',
					'url'=>'"/".$this->name."/edit/".$this->data[$this->name][id]'
				)
			);
			$toolbar_array = $this->GenerateToolbarArray($toolbar_elements)."\n";
			
			//page header
			$header = "\n\t//title\n\t\$this->helpers->htmlx->MenuText1(\$this->localName.': '.LANG_VIEW, 'view.gif');";
			
			$toolbar = "\n\t\n\t//toolbar\n\t\$this->helpers->toolbars->Toolbar(\$tool_buttons);";
			$eva_begin = "\n\n\techo '<table class=\"eva\">';";
			$eva_end = "\n\techo '</table>';";
			
			//generates input rows
			$inputRows = $this->GenerateInputRows($data[elements], 'readonly = "readonly"');
			
			//file content
			$content = $this->phpFileStart.$this->credits.$toolbar_array.$header.$toolbar.$eva_begin.$inputRows.$eva_end.$this->phpFileEnd;
			
			//writes to the file
			fwrite($fp, $content);
			
			//closes the file
			fclose($fp);
		}		

		/**
	 	 * generates index page
	 	 * @param array data
	 	 */
		function GenerateIndexPage($data)
		{
			//making replication
//			$this->copyFiles('index', 'views/'.$_POST[system_name], 'index');
			
			//creates the file with the specified name
			$fp = fopen('app'.SEPARATOR.'views'.SEPARATOR.trim($data[file_name]).SEPARATOR.'index.php', 'w+');
			
			if ($this->tree_structure)
			{
				$redirection = "";
				$addId = '0';
			}
			$toolbar_elements = array
			(
				'0' => array
				(
					'name'=>'add_button',
					'image'=>'btnNew.gif',
					'text'=>'LANG_ADD',
					'url'=>'"/".$this->name."/add/'.$addId.'"'
				)
			);
			$toolbar_array = $this->GenerateToolbarArray($toolbar_elements)."\n";
			
			//generates fields' array
			$fields_array = $this->GenerateGridFieldsArray($data[elements])."\n";
			
			//page header
			$header = "\n\t//title\n\t\$this->helpers->htmlx->MenuText1(\$this->localName.': '.LANG_LIST, 'list.gif');";

			//toolbar
			$toolbar = "\n\t\n\t//toolbar\n\t\$this->helpers->toolbars->Toolbar(\$tool_buttons);";
			
			//generates grid helper
			if ($this->tree_structure)			
				$grid = "\n\t\n\t//grid\n\t\$this->helpers->grids->GridChild(\$this->data[\$this->name], \$fields, {$this->gridSettings[grid][use_filter]});";
			else 
				$grid = "\n\t\n\t//grid\n\t\$this->helpers->grids->Grid(\$this->data[\$this->name], \$fields, {$this->gridSettings[grid][use_filter]});";					
			
			//file content
			$content = $this->phpFileStart.$this->credits.$fields_array.$toolbar_array.$header.$toolbar.$grid.$this->phpFileEnd;
			
			//writes to the file
			fwrite($fp, $content);
			
			//closes the file
			fclose($fp);
		}		

		
		# OTHER GENEARIONS #
				
		/**
		 * Generates toolbar array
		 *
		 * @param array $buttons buttons for the toolbar
		 */
		function GenerateToolbarArray(array $buttons)
		{
			$toolbar =  "\n\t//tool buttons\n\t\$tool_buttons = array\n\t(";
			foreach ($buttons as $button)
			{
				$toolbar .= "\n\t\t'{$button[name]}' => array";
				$toolbar .= "\n\t\t(";
				$toolbar .= "\n\t\t\t'image' => '{$button[image]}',";
				$toolbar .= "\n\t\t\t'text' => {$button[text]},";
				$toolbar .= "\n\t\t\t'url' => {$button[url]}";
				$toolbar .= "\n\t\t),";
			}
			$toolbar .= "\n\t);";
			
			return $toolbar;			
		}

		/**
		 * Generates toolbar array
		 *
		 * @param array $buttons buttons for the toolbar
		 */
		function GenerateGridFieldsArray(array $fields, $grid_name = 'grid')
		{
			$this->gridSettings[$grid_name][use_filter] = 0;
			
			$toolbar =  "\n\t\$fields = array\n\t(";

			foreach ($fields as $field)
			{
			   	if (($field[primary_key])||(!$field[app_name])||(empty($field[title]))) continue;
				
			   	//defines whether to use filter for the grid
			   	if ($field[filter]) $this->gridSettings[$grid_name][use_filter] = 1;
			   	
			   	$field[filter] = ($field[filter] == 1) ? 'true' : 'false';
			   	$field[in_grid] = ($field[in_grid] == 1) ? 'true' : 'false';
			   	
				$toolbar .= "\n\t\t'{$field[app_name]}' => array";
				$toolbar .= "\n\t\t(";
				$toolbar .= "\n\t\t\t'title' => {$field[title]},";
				$toolbar .= "\n\t\t\t'filter' => $field[filter],";
				if($field[id])
				{
					$toolbar .= "\n\t\t\t'id' => '$field[id]',";
					$toolbar .= "\n\t\t\t'model' => '".ereg_replace("^$this->tablePrefix", '', $field[table_name])."',";
				}
				$toolbar .= "\n\t\t\t'in_grid' => $field[in_grid],";
				
				if ($field[use_url])
				{
					$toolbar .= "\n\t\t\t'url' => '{$field[url_controller]}',";
					$toolbar .= "\n\t\t\t'action' => '{$field[url_action]}',";		
					$toolbar .= "\n\t\t\t'id' => '{$field[url_id]}'";		
				}
	
				$toolbar .= "\n\t\t),";
			}
			$toolbar .= "\n\t);";
			
			return $toolbar;			
		}
		
		/**
		 * Returns menu item code
		 *
		 * @param array $data post array
		 * @return string generated string
		 */
		function GetMenuItemCode($data)
		{
			$menu_item = 
"'{$data[system_name]}' => array
(
	'table_name'=>'{$data[table_name]}',
	'text' => {$data[page_title]},
	'url'=>'/{$data[system_name]}/'
),";
			
			return $menu_item;
		}

		/**
		 * Gets language constant definition string(-s)
		 *
		 * @param string|array $data constant name(-s)
		 * @return string
		 */
		function GetConstantsDefinitionCode($data)
		{
			$defines = '';
			if (is_array($data))
			{
				foreach ($data as $elem)
				{
				    $default_translation = strtolower(str_replace('_', ' ', str_replace('LANG_', '', $elem)));
					$defines .= "define('$elem','$default_translation');\n";
				}
			}
			else
			{
			    $default_translation = strtolower(str_replace('_', ' ', str_replace('LANG_', '', $data)));
				$defines = "define('$data','$default_translation')";
			}

			return $defines;
		}
		
		/**
		 * create folder to backup files when we make controller, model, etc. again
		 *
		 * @param string $data controller name
		 * @return string
		 */
		function CreateBackupFolder($data)
		{
			$_SESSION[backup_folder] = $this->backupFolder.$data.'_'.date("d-m-Y_H-i-s");
			mkdir($this->backupFolder.$data.'_'.date("d-m-Y_H-i-s"));			
		}
		
		/**
		 * Copy files for backup
		 *
		 * @param string $file_name which we backup
		 * @param string $folder where will reside backup
		 * @param string $contents what the file will contain in
		 */
		function CopyFiles($file_name, $folder, $container)
		{
			$original = 'app'.SEPARATOR.$folder.SEPARATOR.$file_name;
			$copy = $original.'_temp';
			$copy = str_replace('_', '', $copy);
			$original = str_replace('_', '', $original);
			copy($original.'.php', $copy.'.php');
			rename($copy.'.php', $_SESSION[backup_folder]."/$container.php");		
		}
		
		
		# DATABASE #
		
		/**
		 * Creates stored procedures
		 *
		 * @param array $stored_procedures stored procedures
		 */
		function CreateStoredProcedures($stored_procedures = array())
		{
			if (!empty($stored_procedures))
			{
				$DBGenerator = new DBGenerator();
				$DBGenerator->CreateStoredProcedures($stored_procedures);
			}
		}
		
		/**
		 * Extract stored procedures code
		 *
		 * @param array $stored_procedures stored procedures
		 */
		function ExtractStoredProcedures()
		{
			foreach ($this->request->post[generate] as $proc_name => $value)
			{
				$procedure = $this->controller_model->GetSqlObjectCode($proc_name);
				$fp = fopen($_SESSION[backup_folder]."/$proc_name.txt", 'w') or die(LANG_FILE_OPENING_WAS_NOT_SUCCEDED);

				foreach ($procedure as $key=>$proc_text)
				{
					$text .= $proc_text["Text"]."\n";
				}	
				fwrite($fp, $text);
				fclose($fp);
				$text = '';
			}	
		}
		
		/**
		 * Inserts the meta data into system tables
		 * 
		 * @param $data
		 */
		function InsertSystemData(array $data)
		{
			$DBGenerator = new DBGenerator();
			$DBGenerator->InsertSystemData($data);
		}
		
		
		# MVC PAGES' GENERATION #
		
		/**
	 	 * adds Model
	 	 */
		function AddModel($data)
		{
			//creates the file with the specified name
			$fp = fopen('app'.SEPARATOR.'models'.SEPARATOR.$data[file_name].'.php', 'w+');

			//class comment
			$class_comment = $this->GenerateComment(trim(ucfirst($data['cc_system_name'])).' model class', '', array('version' => '1.0', 'package' => 'models'), 1);
			
			//file beginning
			$start_file = "\n\tClass ".ucfirst($data[cc_system_name])." extends Model \n\t{\n";
			
			//class variables
			if ($data[model_variables])
			{	
				$variables = "\t\t".'public $database_config = \''.$data[database_config]."';\n";
				$variables .= "\t\t".'public $name = \''.$data[system_name]."';\n";
				$variables .= "\t\t".'public $table_name = \''.$data[table_name]."';\n";
				$variables .= "\t\t".'public $stored_procedure_list = \''.$data[stored_procedure_list]."';\n";
				$variables .= "\t\t".'public $stored_procedure_list_paged = \''.$data[stored_procedure_list_paged]."';\n";
				$variables .= "\t\t".'public $stored_procedure_update = \''.$data[stored_procedure_update]."';\n";
				$variables .= "\t\t".'public $stored_procedure_get = \''.$data[stored_procedure_get]."';\n";
				$variables .= "\t\t".'public $stored_procedure_delete = \''.$data[stored_procedure_delete]."';\n";
				$variables .= "\t\t".'public $stored_procedure_insert = \''.$data[stored_procedure_insert]."';\n\n";
			}
			
			//db structure beginning
			$start_db_structure = "\t\t".'public $db_structure = array'."\n\t\t(\n";
			
			//db structure
			$db_structure = '';
			
			//db structure generation
			foreach ($data[elements] as $element)
			{
				if (empty($element[app_name])) continue;
				
				//insert default comment if it is empty
				if (empty($element[comment])) $element[comment] = str_replace('_', ' ', $element[name]);
				
				$db_structure .= "\t\t\t/* $element[comment] */\n";
				$db_structure .= "\t\t\t'{$element[app_name]}' => array\n\t\t\t(\n";
				
				//string variables
				foreach ($this->model_features_string as $feature)
				{
					if ($element[$feature]!='')
						$db_structure .= "\t\t\t\t'$feature' => '{$element[$feature]}',\n";
				}
				
				//boolean variables
				foreach ($this->model_features_boolean as $feature)
				{
					if ($element[$feature] == '1') $value = 'true';
					else $value = 'false';
					$db_structure .= "\t\t\t\t'$feature' => $value,\n";
				}
				
				$db_structure .= "\t\t\t),\n\n";
			}
							
			//db structure ending
			$end_db_structure = "\t\t);";
			
			//file ending
			$end_file = "\n\t}";
			
			//file content
			$content = $this->phpFileStart.$this->credits.$class_comment.$start_file.$variables.$start_db_structure.$db_structure.$end_db_structure.$end_file.$this->phpFileEnd;
			
			//writes to the file
			fwrite($fp, $content);
			
			//closes the file
			fclose($fp);
			
		}
		
		/**
	 	 * adds Controller
	 	 * @param array data
	 	 */
		function AddController($data)
		{				
			//creates the file with the specified name
			$fp = fopen('app'.SEPARATOR.'controllers'.SEPARATOR.trim($data['file_name']).'.php', 'w+');
			
			//class comment
			$class_comment = $this->GenerateComment(trim(ucfirst($data['cc_system_name'])).' controller class', '', array('version' => '1.0', 'package' => 'controllers'), 1);
			
			//file beginning
			$start_file = "\tClass ".trim(ucfirst($data['cc_system_name']))."Controller extends Controller \n\t{\n";
			
			//class variables
			$variables = $this->GenerateControllerClassVariables($data);
			
			if ($data[controller_functions])
			{
				//CLASS FUNCTIONS
				
				//index function
				$index_func = $this->GenerateIndexFunction($data);
				
				//index function
				$add_func = $this->GenerateAddFunction($data);
				
				//index function
				$view_func = $this->GenerateViewFunction($data);
				
				//index function
				$edit_func = $this->GenerateEditFunction($data);
				
				//index function
				$delete_func = $this->GenerateDeleteFunction($data);
			}
			
			//file ending
			$end_file = "\n\t}";
			
			//file content
			$content = $this->phpFileStart.$this->credits.$class_comment.$start_file.$variables.$index_func.$add_func.$view_func.$edit_func.$delete_func.$end_file.$this->phpFileEnd;
			
			//writes to the file
			fwrite($fp, $content);
			
			//closes the file
			fclose($fp);
			
		}
		
		/**
	 	 * adds Views
	 	 */
		function AddViews($data)
		{
			//makes views' directory
			if (!file_exists('app'.SEPARATOR.'views'.SEPARATOR.trim($data[file_name])))
				mkdir('app'.SEPARATOR.'views'.SEPARATOR.trim($data[file_name]));
			
			//generates view page
			$this->GenerateAddPage($data);
			
			//generates view page
			$this->GenerateViewPage($data);
			
			//generates view page
			$this->GenerateEditPage($data);
			
			//generates view page
			$this->GenerateDeletePage($data);
			
			//generates view page
			$this->GenerateIndexPage($data);
		}
		
		/**
	 	 * adds MVC files
	 	 * @param $table we use this param when want to restore a page
	 	 */
		function Add($table = null)
		{			
			$this->SetSystemModelFeatures();
			$this->SetSystemFieldTypes();
									
			if (!empty($table))
			{
				$this->request->post[step] = 1;
				$table = str_replace('@', '_', $table);
				$this->request->post['table_name'] = $table;
			}
			
			//if we posted smth
			if ((!empty($this->request->post)))
			{
				//if table name for generation was specified
				if ($this->request->post[step] == '1')
				{
					$schema = $this->controller_model->GetSchema(array('table_name'=>"{$this->request->post[table_name]}"));

					//find out if there is a parent_id field
					foreach ($schema as $element)
					{
						if ($element[column_name] == $this->parentId)
							$this->tree_structure = true;
					}

					//stored procedures generation
					//if it is restoring, we get procedures from SESSION
					if (empty($table))
					{
						$DBGenerator = new DBGenerator();
						$this->data[stored_procedures] = $DBGenerator->GenerateStoredProcedures($schema);
					}
					else 
					{
						$this->data[stored_procedures] = $_SESSION[procedures];
						unset($_SESSION[procedures]);
					}
					
					//gets name from the table name
					$this->data[controller] = eregi_replace("^$this->tablePrefix", '', $schema[0][table_name]);
					$this->data[name] = $this->Singularize($this->data[controller]);
					
					$i = 0;
					foreach ($schema as $element)
					{
						if ((in_array($element[column_name], $this->escapedFieldNames))) continue;
						$this->data[elements][$i][app_name] = ereg_replace("^{$this->data[name]}_", '', $element[column_name]);
						$this->data[elements][$i][name] = $element[column_name];
						$this->data[elements][$i][title] = $this->StringToLanguageConstant($this->data[elements][$i][app_name]);
						$this->data[elements][$i][type] = $element[data_type];
						$this->data[elements][$i][table_name] = ($schema[0][table_name] == $element[table_name]) ? '' : $element[table_name];
						$this->data[elements][$i][length] = $element[max_length];
						$this->data[elements][$i][foreign_model] = $this->CamelCase(ereg_replace("^$this->tablePrefix", '', $element[foreign_table]));
						$this->data[elements][$i][not_null] = ($element[is_null] == 'NO') ? 1 : 0;
						$this->data[elements][$i][primary_key] = $element[primary_key];
						$this->data[elements][$i][comment] = $element[column_comment];
						$this->data[elements][$i][default_value] = $element[default_value];

						//if password
						if (($element[data_type] == 'varchar') && ($element[max_length] == 32))
							$this->data[elements][$i][sub_type] = 'password';
						
						if (!empty($this->data[elements][$i][table_name]))
						{
							$this->data[elements][$i-1][title] = $this->data[elements][$i][title];
						} 
						
						$i++;
						$this->SetDefaults();
					}	
					
				}
				else
				{
					//CamelCased system name
					$this->request->post[cc_system_name] = $this->CamelCase($this->request->post[system_name]);
					
					//file and directory name
					$this->request->post[file_name] = strtolower($this->request->post[cc_system_name]);
					$_SESSION[mvc] = $this->request->post;
					
					foreach ($this->request->post[elements] as &$elem)
					{
						//removes unnecessary fields from the post array
						if ($elem[disable])
						{
							$elem = array();
							continue;
						}
						if ($elem[filter] && (!empty($elem[table_name])))
						{
							$elem[id] = $previous_elem[name];
						}
						$previous_elem = $elem;
					}					
					
					//find out if there is a parent_id field
					foreach ($this->request->post[elements] as $value)
					{
						if ($value[name] == $this->parentId)
							$this->tree_structure = true;
					}		
					
					//create backup of a page
					$this->all_backuped = File::BackupPage($this->backupFolder, $this->request->post[system_name], $this->request->post[file_name], $this->storedProcedurePrefix, $this->max_quantity, $this->backupDate);
					
					//add files
					$this->addModel($this->request->post);
					$this->addController($this->request->post);
					$this->addViews($this->request->post);
					
					//creating stored procedures code
					$this->CreateStoredProcedures($this->request->post[stored_procedures]);

					//insert into system tables
					$this->InsertSystemData($this->request->post);
					
					//menu item (for the menus file)
					$this->request->post[menu_item] = $this->GetMenuItemCode($this->request->post);
	
					//language constants definition (for the language file(-s))
					array_push(&$this->languageConstants, $this->request->post[page_title]);
					$this->request->post[constant_defines] .= $this->GetConstantsDefinitionCode($this->languageConstants);
					
					$this->data = $this->request->post;
					
					$this->data[generated_code_menu] = $this->GetGeneratedCodeMenuArray();
				}
			}
			else
			{
				$this->SetDefaults();
			}
			
			//gets helpers list
			$this->data[helper_files] = $this->GetFileNames("././app/includes/helpers/", "php");
			
			//gets JS files list
			$this->data[js_files] = $this->GetFileNames("././app/includes/js/", "js");
			
			$this->data[code_generator_menu] = $this->ElementsToTreeMenu($this->data[elements], $this->request->post[table_name], $this->data[stored_procedures]);
			
		}
		
		/**
	 	 * restores page (controller, view, model, stored procedures)
	 	 * @param string $page_name controller name
		 * @param string $time time when backup was created
		 * @param string $file_name PHP file-name
	 	 */
		function RestorePage($page_name, $file_name, $time)
		{
			//underlines were substituted by @ due to features of framework
			$page_name = str_replace('@', '_', $page_name);
			$file_name = str_replace('@', '_', $file_name);
			$time = str_replace('@', '_', $time);
			
			$this->data[file_name] = $file_name;

			//copying files from backup
			File::CopyFilesAndFolders($this->backupFolder."$page_name/controllers/".$file_name."_".$time.'.php', 'app'.SEPARATOR.'controllers'.SEPARATOR.trim($file_name).'.php');
			File::CopyFilesAndFolders($this->backupFolder."$page_name/models/".$file_name."_".$time.'.php', 'app'.SEPARATOR.'models'.SEPARATOR.trim($file_name).'.php');
			File::CopyFilesAndFolders($this->backupFolder."$page_name/views/".$file_name."_".$time, 'app'.SEPARATOR.'views'.SEPARATOR.trim($file_name));
			
			//scanning directory of stored procedures and executing them
			$dir_contents = scandir($this->backupFolder."$page_name/stored_procedures/".$page_name."_".$time);
	       	foreach ($dir_contents as $item) 
	       	{
	            if ($item != '.' && $item != '..') 
	            {	            	
	            	//here we get names for deleting st.procs and read the backups to create new st.procs
	            	$proc_name = ereg_replace('_[0-9-]{10}_[0-9-]{8}.txt$', '', $item);
	            	$this->procedures[$proc_name] = '';
	                $file_strings = file($this->backupFolder."$page_name/stored_procedures/{$page_name}_{$time}/".$item);	                	                
	                
	                foreach ($file_strings as $value)
	                {
	                	$temp = trim($value);
	                	if (!empty($temp))
	                		$this->procedures[$proc_name] .= $value;
	                }	
	            }	            
	       	}   
	       	$this->CreateStoredProcedures($this->procedures); 
	       	//delete the latest page not to keep a copy for nothing
	       	File::DeleteEndPage($page_name, $this->backupFolder, $this->max_quantity, 1);
	       	
		}

		/**
		 * Chooses table for code generation
		 *
		 */
		function ChooseTable()
		{
			//if we posted smth
			if ((!empty($this->request->post)))
			{
				
			}
			else
			{
				$this->data[tables] = $this->controller_model->GetTables(array());
			}
		}
		
	}
?>